using System.Collections.Generic;
using Gl.SettingsManager.Providers.RegistrySettings;
using Microsoft.Win32;
using System;
namespace Gl.SettingsManager.Providers
{
	public enum RegistryFolder
	{
		CurrentUser,
		LocalMachine
	}

	public class RegistrySettingsProvider : ISettingsProvider
	{
		private RegistryFolder _registryFolder = RegistryFolder.CurrentUser;
		private readonly string _settingsRegistryRoot = "SettingsManagerData";
		private const string _softwareRegistryKeyName = "SOFTWARE";
		private List<SettingsCollection> _settings = new List<SettingsCollection>();

		public string SettingsRegistryRoot
		{
			get { return _settingsRegistryRoot; }
		}

		public RegistryFolder RegistryFolder
		{
			get { return _registryFolder; }
			set { _registryFolder = value; }
		}

		public RegistrySettingsProvider(string settingsRegistryRoot)
		{
			_settingsRegistryRoot = settingsRegistryRoot;
		}

		public RegistrySettingsProvider() { }

		private RegistryKey RootRegistry
		{
			get
			{
				RegistryKey key = RegistryFolder == RegistryFolder.CurrentUser ?
					Registry.CurrentUser : Registry.LocalMachine;
				key = key.OpenSubKey(_softwareRegistryKeyName, true);
				RegistryKey settingsKey = key.OpenSubKey(_settingsRegistryRoot, true);
				if (settingsKey == null)
					settingsKey = key.CreateSubKey(_settingsRegistryRoot, RegistryKeyPermissionCheck.ReadWriteSubTree);

				return settingsKey;
			}
		}

		#region ISettingsProvider Members

		SettingsCollection ISettingsProvider.GetSettings(string typeName, string context)
		{
			try
			{
				SettingsCollection collection = _regHelper.GetSettings(RootRegistry, typeName, context);
				_settings.Add(collection);
				return collection;
			}
			catch (Exception ex)
			{
				throw new SettingsException(ex, Exceptions.ErorrReadingRegistry, ex.Message);
			}
		}

		void ISettingsProvider.Save()
		{
			try
			{
				foreach (SettingsCollection settings in _settings)
					_regHelper.SaveSettings(settings, RootRegistry);
			}
			catch (Exception ex)
			{
				throw new SettingsException(ex, Exceptions.ErorrReadingRegistry, ex.Message);
			}
		}

		void ISettingsProvider.InitializeProvider()
		{
			_regHelper = new RegistryHelper();
		}

		private RegistryHelper _regHelper;

		bool ISettingsProvider.IsInitialized
		{
			get { return _regHelper != null; }
		}

		void ISettingsProvider.ResetSettings()
		{
			List<string> regKeys = new List<string>();
			foreach (string subKeyName in RootRegistry.GetSubKeyNames())
				regKeys.Add(subKeyName);
			foreach (string key in regKeys)
				RootRegistry.DeleteSubKeyTree(key);
		}

		#endregion
	}
}
